package cn.itcast.service.impl;

import cn.itcast.dao.MenuDao;
import cn.itcast.dao.UserDao;
import cn.itcast.entity.PageResult;
import cn.itcast.entity.QueryPageBean;
import cn.itcast.pojo.Menu;
import cn.itcast.pojo.Role;
import cn.itcast.pojo.User;
import cn.itcast.service.MenuService;
import cn.itcast.service.RoleService;
import cn.itcast.service.UserService;
import cn.itcast.util.IdService;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author FXB
 * @createTime 2021年11月15日 14:48:00
 */
@Service
@Transactional
@Slf4j
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuDao menuDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private IdService idService;

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    /**
     * 查询所有菜单
     * @return
     */
    @Override
    public List<Menu> findAll() {

        return menuDao.findAll();

    }

    /**
     * 分页查询所有菜单
     * @param currentPage
     * @param pageSize
     * @param queryString
     * @return
     */
    @Override
    public PageResult pageQuery(Integer currentPage, Integer pageSize, String queryString) {
        log.info("currentPage:{},pageSize:{},queryString:{}",currentPage,pageSize,queryString);
        PageHelper.startPage(currentPage,pageSize);


        Page<Menu> page=menuDao.findByCondition(queryString);

        //分页出来的数据
        List<Menu> menuList = page.getResult();

        List<Menu> newMenuList = getMenuSon(menuList);


        return new PageResult(page.getTotal(),newMenuList);


    }

    //将查询出来的菜单，把子菜单添加到父类
    private List<Menu> getMenuSon(List<Menu> menuList) {
        //新的集合
        List<Menu> newMenuList =new ArrayList<>();
        for (Menu menu : menuList) {
            Menu newMenu = new Menu();
            newMenu.setId(menu.getId());
            newMenu.setName(menu.getName());
            newMenu.setLinkUrl(menu.getLinkUrl());
            newMenu.setPriority(menu.getPriority());
            newMenu.setIcon(menu.getIcon());
            newMenu.setDescription(menu.getDescription());
            newMenu.setParentMenuId(menu.getParentMenuId());
            newMenu.setLevel(menu.getLevel());
            newMenu.setRoles(menu.getRoles());

            //获取到子集合,封装到menu
            Integer menuId = menu.getId();
            List<Menu> parentMenuList = menuDao.findParentMenuIdById(menuId);
            newMenu.setChildren(parentMenuList);


            newMenuList.add(newMenu);
        }
        return newMenuList;
    }

    /**
     * 根据ID查询菜单信息
     * @param id
     * @return
     */
    @Override
    public Menu findById(Integer id) {
        return menuDao.findById(id);
    }

    /**
     * 根据ID查询下面所有子菜单id信息
     * @param id
     * @return
     */
    @Override
    public List<Integer> findParentMenuIdById(Integer id) {
        //获取到该id下面的菜单信息
        List<Menu> menuList = menuDao.findParentMenuIdById(id);
        List<Integer> menuId= new ArrayList<>();
        //获取到id
        for (Menu menu : menuList) {

            log.info("id:{},对应的的子菜单{}",id,menu.getId());
            menuId.add(menu.getId());
        }

        return menuId;
    }



    /**
     * 根据id删除菜单信息数据
     * @param menuList
     */
    @Override
    public Boolean deleteById(List<Integer> menuList) {

        //获取到每个ID,进行删除
        for (Integer menuId : menuList) {

            //判断用户菜单表是否有关联
            Integer menuAndUser = menuDao.findMenuAndUserById(menuId);
            log.info("用户菜单表存在几个关联数据："+menuAndUser);
            if(menuAndUser !=0){
                return false;
            }



            log.info("要删除的ID-----:"+menuId);
            //删除menu表
            menuDao.deleteById(menuId);
            //删除menu_permission表
            menuDao.deleteMenuPermissionsById(menuId);

        }
        return true;



    }

    /**
     * 查询菜单关联的权限表
     * @param menuid
     * @return
     */
    @Override
    public Integer[] selectPermissionsIds(Integer menuid) {
        return  menuDao.selectPermissionsIds(menuid);

    }

    /**
     * 更新菜单数据
     * @param menu
     */
    @Override
    public void edit(Menu menu) {
        menuDao.update(menu);
    }

    /**
     * 修改菜单权限表
     * @param permissionIds
     */
    @Override
    public void updateMenuPermissions(List<Integer> permissionIds, Menu menu) {

        //获取到要修改的菜单ID
        Integer menuId = menu.getId();

       //先删除原先之前的所有数据
        menuDao.deleteMenuPermissionsById(menuId);
        log.info("删除菜单权限信息成功！");

        for (Integer permissionId : permissionIds) {
            //新增数据
            log.info("新增菜单权限信息：menID:{},permissionId:{}",menuId,permissionId);
            menuDao.saveMenuPermissions(menuId,permissionId);
        }




    }

    /**
     * 新增菜单
     * @param menu
     * @param permissionIds
     */
    @Override
    public void add(Menu menu, List<Integer> permissionIds) {
        //设置redis自增ID
        Long menuId = idService.createId();

        //新增菜单表
        menu.setId(new Long(menuId).intValue());
        menuDao.saveMenu(menu);

        log.info("新增菜单信息："+menu);
        //新增菜单权限表，需要先是否为空
        if (permissionIds.size()!=0){
            //转换成int类型
            Integer menuid=new Long(menuId).intValue();
            for (Integer permissionId : permissionIds) {
                //新增数据
                log.info("新增菜单权限信息：menID:{},permissionId:{}",menuid,permissionId);
                menuDao.saveMenuPermissions(menuid,permissionId);
            }
        }
    }

    /**
     * 动态菜单
     *根据用户名进行查询菜单
     * @param username
     * @return
     */
    @Override
    public Set<Menu> findMenuByUsername(String username) {

        //根据用户名查询user对象
        User user = userDao.findByName(username);

        //根据userID得到角色信息集合   一个对象有多个角色集合
        Integer userId = user.getId();
        Integer[] roleIdInt = userService.selectedRoleId(userId);

        HashSet<Menu> menuSet = new HashSet<Menu>();
        //遍历角色信息，得到角色ID
        for (Integer roleId : roleIdInt) {
            //得到角色的菜单ID集
            Integer[] menuInt = roleService.findIdByMenu(roleId);
            //todo 得到ID集冒泡排序

            //得到具体的菜单ID
            for (Integer menuid : menuInt) {
                //得到菜单信息
                Menu menu = menuDao.findById(menuid);
                //封装到set集合
                menuSet.add(menu);
            }
        }

        //遍历找出一级菜单
        Set<Menu> newMenuSet = menuSet.stream().filter(menu -> menu.getParentMenuId() == 0).collect(Collectors.toSet());

        //遍历一级菜单,根据二级菜单的parentMenuId和一级菜单id找到对应的二级菜单
        for (Menu menu : newMenuSet) {
            //从查到的所有菜单中找到一级菜单对应的二级菜单
            List<Menu> childern = menuSet.stream()
                    .filter(child -> menu.getId().equals(child.getParentMenuId()))
                    .collect(Collectors.toList());
            //将二级菜单设置到一级菜单的children中
            menu.setChildren(childern);
        }
          return newMenuSet;
    }


}
